package common.util.generate.properties;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author liubo
 * @created 2020-06-15 17:03
 */
public class TableFieldProperties implements Serializable {

    /**
     * 是否为主键
     */
    private boolean pkField;

    /**
     * 是否为公共字段
     */
    private boolean commonField;

    /**
     * get set 方法 后面的 那个在字符串
     * getPkField -> PkField
     */
    private String getsetMethodName;

    /**
     * 字段名称
     */
    private String fieldName;

    /**
     * 字段在实体类中的名称
     */
    private String entityFieldName;

    /**
     * 字段注解
     */
    private String comments;

    /**
     * 字段 类型(数据库)
     */
    private String fieldType;

    /**
     * 字段 类型(JAVA) -> java.util.Date
     */
    private String javaTypePath;

    /**
     * 字段 类型(JAVA) -> Date
     */
    private String javaSimpleType;

    /**
     * 最大长度
     */
    private Integer maxLength;

    /**
     * 是否为空
     */
    private Boolean isNull;

    /**
     * 默认值
     */
    private Object dataDefault;

    /**
     * 精度
     */
    private Integer dataPrecision;

    /**
     * 小数点后位数
     */
    private Integer dataScale;

    /**
     * 默认值长度
     */
    private Integer defaultLength;

    /**
     * 注释拆分
     */
    private  List<NotesProperties> notes;

    public String getFieldName() {
        return fieldName;
    }

    public void setFieldName(String fieldName) {

        this.setEntityFieldName(this.dbForDBToFistLowercaseHump(fieldName));
        if(this.entityFieldName.length() >1){
            if(Character.isUpperCase(this.entityFieldName.charAt(1))){
                this.setGetsetMethodName(this.entityFieldName);
            }else{
                this.setGetsetMethodName(
                        this.entityFieldName.substring(0, 1).toUpperCase()+
                        this.entityFieldName.substring(1,this.entityFieldName.length())
                );
            }
        }else{
            this.setGetsetMethodName(this.entityFieldName.toUpperCase());
        }

        this.fieldName = fieldName;
    }

    public String getComments() {
        return comments;
    }

    public void setComments(String comments) {
        this.comments = comments;
    }

    public String getFieldType() {
        return fieldType;
    }

    public void setFieldType(String fieldType,ParamProperties properties) {
        try {
            Class clazz = this.dbForDBTypeToJavaClass(fieldType);
            this.setJavaTypePath(clazz.getName());
            this.setJavaSimpleType(clazz.getSimpleName());
            if(!this.getJavaTypePath().startsWith("java.lang")){
                if(this.getJavaTypePath().equals(Date.class.getName())){
                    properties.setHasDate(true);
                }
                PackageProperties pk = properties.getPk();
                if(null == pk){
                    pk = new PackageProperties();
                }
                Set<String> list = pk.getEntityImportPackages();
                if( null == list ){
                    list = new HashSet<>();
                }
                list.add(this.javaTypePath);
                pk.setEntityImportPackages(list);
                properties.setPk(pk);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        this.fieldType = this.getMybatisDbType(fieldType);
    }

    public String getMybatisDbType(String dbType){
        if(dbType.toUpperCase().startsWith("NUMBER")){
            return "NUMBER";
        }else if(dbType.toUpperCase().startsWith("DATE")){
            return "DATE";
        }else if(dbType.toUpperCase().startsWith("VARCHAR2")||dbType.toUpperCase().startsWith("VARCHAR")
                ||dbType.toUpperCase().startsWith("CHAR")){
            return "VARCHAR";
        }else if(dbType.toUpperCase().startsWith("TIMESTAMP")||dbType.toUpperCase().startsWith("DATETIME")){
            return "TIMESTAMP";
        }else if(dbType.toUpperCase().startsWith("INT")||dbType.toUpperCase().startsWith("INTEGER")){
            return "INTEGER";
        }else if(dbType.toUpperCase().startsWith("BIGINT")){
            return "Long";
        }else if(dbType.toUpperCase().startsWith("DECIMAL")||dbType.toUpperCase().startsWith("NUMERIC")){
            return "DECIMAL";
        }else{
            throw new RuntimeException("dbTypeToJava:数据库类型--->"+dbType+"没有找到对应的java类");
        }
    }
    public String getJavaTypePath() {
        return javaTypePath;
    }

    public void setJavaTypePath(String javaTypePath) {
        this.javaTypePath = javaTypePath;
    }

    public String getJavaSimpleType() {
        return javaSimpleType;
    }

    public void setJavaSimpleType(String javaSimpleType) {
        this.javaSimpleType = javaSimpleType;
    }

    public Integer getMaxLength() {
        return maxLength;
    }

    public void setMaxLength(Integer maxLength) {
        this.maxLength = maxLength;
    }

    public Boolean getNull() {
        return isNull;
    }

    public void setNull(Boolean aNull) {
        isNull = aNull;
    }

    public Object getDataDefault() {
        return dataDefault;
    }

    public void setDataDefault(Object dataDefault) {
        this.dataDefault = dataDefault;
    }

    public Integer getDataPrecision() {
        return dataPrecision;
    }

    public void setDataPrecision(Integer dataPrecision) {
        this.dataPrecision = dataPrecision;
    }

    public Integer getDataScale() {
        return dataScale;
    }

    public void setDataScale(Integer dataScale) {
        this.dataScale = dataScale;
    }

    public Integer getDefaultLength() {
        return defaultLength;
    }

    public void setDefaultLength(Integer defaultLength) {
        this.defaultLength = defaultLength;
    }

    public String getEntityFieldName() {
        return entityFieldName;
    }

    public void setEntityFieldName(String entityFieldName) {
        this.entityFieldName = entityFieldName;
    }

    public Class dbForDBTypeToJavaClass(String dbType) throws Exception{

        if(dbType.toUpperCase().startsWith("CHAR")
                || dbType.toUpperCase().startsWith("VARCHAR")
                || dbType.toUpperCase().startsWith("VARCHAR2")
                || dbType.toUpperCase().startsWith("LONGVARCHAR")){
            return String.class;
        }else if(dbType.toUpperCase().startsWith("NUMERIC")
                ||dbType.toUpperCase().startsWith("DECIMAL")
                ||dbType.toUpperCase().startsWith("NUMBER")){
            return BigDecimal.class;
        }else if(dbType.toUpperCase().startsWith("BIT")){
            return Boolean.class;
        }else if(dbType.toUpperCase().startsWith("TINYINT")){
            return Byte.class;
        }else if(dbType.toUpperCase().startsWith("SMALLINT")){
            return Short.class;
        }else if(dbType.toUpperCase().startsWith("INTEGER")
                ||dbType.toUpperCase().startsWith("INT")){
            return Integer.class;
        }else if(dbType.toUpperCase().startsWith("BIGINT")){
            return Long.class;
        }else if(dbType.toUpperCase().startsWith("REAL")
                ||dbType.toUpperCase().startsWith("FLOAT")){
            return Float.class;
        }else if(dbType.toUpperCase().startsWith("DOUBLE")){
            return Double.class;
        }else if(dbType.toUpperCase().startsWith("BINARY")
                ||dbType.toUpperCase().startsWith("VARBINARY")
                ||dbType.toUpperCase().startsWith("LONGVARBINARY")){
            return Byte[].class;
        }else if(dbType.toUpperCase().startsWith("DATE")){
            return Date.class;
        }else if(dbType.toUpperCase().startsWith("TIME")){
            return Date.class;
        }else if(dbType.toUpperCase().startsWith("TIMESTAMP")
                ||dbType.toUpperCase().startsWith("DATETIME")){
            return Date.class;
        }else{
            throw new RuntimeException("dbTypeToJava:数据库类型--->"+dbType+"没有找到对应的java类");
        }
    }
    /**
     * @example bd_item_info--->bdItemInfo
     * @param
     * @return String
     *
     */
    public String dbForDBToFistLowercaseHump(String str){
        str = str .toLowerCase();
        StringBuffer sb = new StringBuffer();
        String[] fields = str.split("_");
        String temp = null;
        for ( int i = 0 ; i < fields.length ; i++ ) {
            temp = fields[i].trim();
            if(i==0){
                sb.append(temp.substring(0, 1).toLowerCase()).append(temp.substring(1));
            }else{
                sb.append(temp.substring(0, 1).toUpperCase()).append(temp.substring(1));
            }
        }
        return sb.toString();
    }

    public boolean isPkField() {
        return pkField;
    }

    public void setPkField(boolean pkField) {
        this.pkField = pkField;
    }

    public boolean isCommonField() {
        return commonField;
    }

    public void setCommonField(boolean commonField) {
        this.commonField = commonField;
    }

    public void setFieldType(String fieldType) {
        this.fieldType = fieldType;
    }

    public String getGetsetMethodName() {
        return getsetMethodName;
    }

    public void setGetsetMethodName(String getsetMethodName) {
        this.getsetMethodName = getsetMethodName;
    }

    public List<NotesProperties> getNotes() {
        return notes;
    }

    public void setNotes(List<NotesProperties> notes) {
        this.notes = notes;
    }
}
